#pragma once

#include "InputSystemPrereq.h"
namespace ne{
class InputSystem : public OIS::KeyListener, public OIS::MouseListener,  public Ogre::WindowEventListener {
public:
	InputSystem(void);
	~InputSystem(void);
	
	void _Capture();	// do not call directly, as this is only supposed to be called once per frame
	void _Init(Ogre::RenderWindow* renderWindow);	// do not call directly, this is called once during system initialization
	void _Shut();	// do not call directly as this is called upon system shutdown

	bool IsKeyDown(int key);	// returns true if a key is down (use OIS::KC_X)
	bool IsKeyPressed(int key);	// returns true if the key has been pressed (use OIS::KC_X)
	bool IsKeyReleased(int key);	// returns true if the key has been released (use OIS::KC_X)
	
	bool IsMouseButtonDown(int btn);
	bool IsMouseButtonPressed(int btn);
	bool IsMouseButtonReleased(int btn);

	bool IsJoyStickButtonDown(int btn, int joystickID);
	bool IsJoyStickButtonPressed(int btn, int joystickID);
	bool IsJoyStickButtonReleased(int btn, int joystickID);

	// This is a set of user defined buttons that can be declared using a text string, you can bind any input device (mouse, joystick, keyboard etc to any text string)
	bool IsButtonDown(const Ogre::String& buttonName, int joystickId = 0);
	bool IsButtonPressed(const Ogre::String& buttonName, int joystickId = 0);
	bool IsButtonReleased(const Ogre::String& buttonName, int joystickId = 0);

	bool IsJoyStickPovDown(int pov, int joystickID);
	bool IsJoyStickPovPressed(int pov, int joystickID);
	bool IsJoyStickPovReleased(int pov, int joystickID);

	void AddButton(const Ogre::String& name, int type, int id);
	void RemoveButton(const Ogre::String& name);
	void RemoveButton(const Ogre::String& name, int type, int id);
	float GetJoystickAxis(int axis, int joystickID = 0);
	int GetJoystickPov(int joystickID = 0);

	const OIS::MouseState& GetMouseState() const { return m_mouse->getMouseState(); }

private:
	void windowResized(Ogre::RenderWindow* render_window);
	void windowClosed(Ogre::RenderWindow* render_window);
	bool keyPressed(const OIS::KeyEvent&);
	bool keyReleased(const OIS::KeyEvent&);
	
	bool mouseMoved(const OIS::MouseEvent&);
	bool mousePressed(const OIS::MouseEvent&, OIS::MouseButtonID);
	bool mouseReleased(const OIS::MouseEvent&, OIS::MouseButtonID);

	OIS::Mouse* m_mouse;
	OIS::Keyboard* m_keyboard;
	OIS::InputManager*	m_oisInputManager;
	std::vector<ne::JoyStick*> m_joysticks;
	Ogre::RenderWindow* m_renderWindow;

	
	bool m_keys[ne::KEYBOARD_KEYS];
	bool m_lastKeys[ne::KEYBOARD_KEYS];
	bool m_mouseButtons[ne::MOUSE_BUTTONS];
	bool m_lastMouseButtons[ne::MOUSE_BUTTONS];
	typedef std::map<Ogre::String, std::vector<std::pair<int,int>>> ButtonList;
	ButtonList m_buttons;	//Button name, type, and key/button id
	//std::vector<NEngine::Button> s_buttons;
};
}